<?php

//登录
define("CMPP_CONNECT", 0x00000001);
//短信提交
define("CMPP_SUBMIT", 0x00000004);

define("SP_VERSION", 12);
define("SP_HOST", "211.138.155.249");
define("SP_PORT", "8855");

define("SEQUENCE_ID", 2);
define("SP_SOURCE_ADDR", "913175");
define("SP_PASSWORD", "400hjl9fP");
define("SP_SOURCE_ID", "10658209");


class np_cmpp
{


    static private function send_to_ISMG($socket_obj)
    {
        $msg_id = "";
        $pk_total = 1;
        $pk_number = 1;
        $registered_delivery = 1;
        $msg_level = 0;
        $service_id = "mgtv_12345";
        $fee_userType = "2"; //计费类型
        $fee_terminal_id = "";
        $tp_pid = 0;
        $tp_udhi = 0;
        $msg_fmt = 0;
        $msg_src = SP_SOURCE_ADDR;
        $fee_type = "01";
        $fee_code = 1;
        $valid_time = date("YmdHis");
        $at_time = "";
        $src_id = SP_SOURCE_ID;
        $destUsr_tl = 1;
        $dest_terminal_id = "15060138819"; //必须是移动手机号码

        $msg_content = self::utf8_unicode("这是我的测试message");
        $msg_length = strlen($msg_content);
        $reserve = "";


        $message_body = pack("a8", $msg_id);
        $message_body .= pack("H", $pk_total);
        $message_body .= pack("H", $pk_number);
        $message_body .= pack("H", $registered_delivery);
        $message_body .= pack("H", $msg_level);
        $message_body .= pack("a10", $service_id);
        $message_body .= pack("H", $fee_userType);
        $message_body .= pack("a21", $fee_terminal_id);
        $message_body .= pack("H", $tp_pid);
        $message_body .= pack("H", $tp_udhi);
        $message_body .= pack("H", $msg_fmt);
        $message_body .= pack("a6", $msg_src);
        $message_body .= pack("a2", $fee_type);
        $message_body .= pack("a6", $fee_code);
        $message_body .= pack("a17", $valid_time);
        $message_body .= pack("a17", $at_time);
        $message_body .= pack("a21", $src_id);
        $message_body .= pack("H", $destUsr_tl);
        $message_body .= pack("a21", $dest_terminal_id);
        $message_body .= pack("H", $msg_length);
        $message_body .= pack("a{$msg_length}", $msg_content);
        $message_body .= pack("a8", $reserve);

        //生成消息头
        $message_header = self::build_message_header(CMPP_SUBMIT, strlen($message_body));
        $message = $message_header . $message_body;

        self::dump("开始发送短消息");
        //发送;
        socket_write($socket_obj, $message) or die("Write failed\n");
        $response = "";
        while ($buff = socket_read($socket_obj, 1024, PHP_BINARY_READ))
        {
            $response .= $buff;
        }
        self::dump("send_sms from response:" . bin2hex($response));
        file_put_contents("send.dat", $response);
        if ($response)
        {
            //去掉消息头
            $response_body = substr($response, 12);
            //$result = unpack("a8Msg_Id/HResult", $response_body);
            $msg_id = unpack("H*", substr($response_body, 0, 8));
            $status = unpack("H*", substr($response_body, 8, 1));

            $result['msg_id'] = $msg_id[1];
            $result['status'] = $status[1];
            self::dump("发送短信返回结果" . var_export($result));
        }

    }

    static private function connect_ISMG($socket)
    {
        //消息体
        $timestamp = date("mdHis");
        $authenticator_source = md5(SP_SOURCE_ADDR . str_repeat("\0", 9) . SP_PASSWORD . $timestamp, true);
        self::dump("authenticator_source :" . bin2hex($authenticator_source));
        //$timestamp = date("mdHis", strtotime($timestamp));
//        $message_body = pack("a6", SP_SOURCE_ADDR) . pack("a16", $authenticator_source) . pack("H", SP_VERSION) . pack("N", $timestamp);
        $message_body = pack("a6", SP_SOURCE_ADDR) . pack("a16", $authenticator_source) . pack("H", SP_VERSION) . pack("N", (int)$timestamp);
        //生成消息头
        $message_header = self::build_message_header(CMPP_CONNECT, strlen($message_body));

        $message = $message_header . $message_body;
        //file_put_contents("tmp/connect_request_".date("Y_m_d_H_i_s").".dat", $message );
        self::dump("开始登录梦网");
        //$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create  socket\n"); // 创建一个Socket
        $connection = socket_connect($socket, SP_HOST, SP_PORT) or die("Could not connet server\n");    //  连接
        socket_write($socket, $message) or die("Write failed\n"); // 数据传送 向服务器发送消息

        $response = socket_read($socket, 1024, PHP_BINARY_READ);
        // file_put_contents("tmp/connect_respose_".date("Y_m_d_H_i_s").".dat", $response );
        if ($response)
        {
            //去掉消息头
            $response_body = substr($response, 12);
            //$result = unpack("Nstatus/H16authcode/Nversion", $response_body);
            $status = unpack("H*", substr($response_body, 0, 1));
            $authenticator_ISMG = unpack("H*", substr($response_body, 1, 16));
            $version = unpack("H*", substr($response_body, 17));


            $result['status'] = hexdec($status[1]);
            $result['authenticator_ISMG'] = $authenticator_ISMG[1];
            $result['version'] = $version[1];
            self::dump("登录梦网结果" . var_export($result));
            if ($result['status'] == 0)
            {
                return true;
            }
            return false;
        }
        return false;
    }

    /**
     * @param $command_id 命令ID
     * @param $body_length 消息体长度
     * @return string 消息头信息
     * @author huayi.cai
     * 生成cmpp消息头
     */
    static private function build_message_header($command_id, $body_length)
    {
        $message_total = $body_length + 12;
        //消息头
        $message_header = pack("NNN", $message_total, $command_id, SEQUENCE_ID);

        return $message_header;
    }

    static public function utf8_unicode($name)
    {
        $name = iconv('UTF-8', 'UCS-2', $name);
        $len = strlen($name);
        $str = '';
        for ($i = 0; $i < $len - 1; $i = $i + 2)
        {
            $c = $name[$i];
            $c2 = $name[$i + 1];
            if (ord($c) > 0)
            {   //两个字节的文字
                $str .= '\u' . base_convert(ord($c), 10, 16) . str_pad(base_convert(ord($c2), 10, 16), 2, 0, STR_PAD_LEFT);
                //$str .= base_convert(ord($c), 10, 16).str_pad(base_convert(ord($c2), 10, 16), 2, 0, STR_PAD_LEFT);
            }
            else
            {
                $str .= '\u' . str_pad(base_convert(ord($c2), 10, 16), 4, 0, STR_PAD_LEFT);
                //$str .= str_pad(base_convert(ord($c2), 10, 16), 4, 0, STR_PAD_LEFT);
            }
        }
        $str = strtoupper($str);//转换为大写
        return $str;
    }

    static private function dump($str)
    {
        echo "--------------".date("Y-m-d H:i:s")."-----------------" . "\r\n";
        echo $str . "\r\n";
        echo "-----------" . "\r\n";
    }


    static public function  send_sms()
    {
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        //登录梦网
        $ret = self::connect_ISMG($socket);
        if($ret === true)
        {
            //发送短信
            self::send_to_ISMG($socket);
        }
        socket_close($socket);

    }
}


np_cmpp::send_sms();

?>